<?php

namespace App\Console\Commands\Settlement;

use App\Models\Settlement;
use App\Models\SubSettlement;
use App\Services\FourElement\FourElementVerificationResult;
use App\Services\FourElement\FourElementVerifier;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class VerifySettlementFourElementsCommand extends Command
{
    protected $signature = 'settlement:verify-four-elements {settlementNumber : 结算单编号}';

    protected $description = '对指定结算单的子结算条目执行四要素验证';

    protected FourElementVerifier $verifier;

    public function __construct(FourElementVerifier $verifier)
    {
        parent::__construct();
        $this->verifier = $verifier;
    }

    public function handle(): int
    {
        $settlementNumber = $this->argument('settlementNumber');

        $settlement = Settlement::with('subSettlements')
            ->where('settlement_number', $settlementNumber)
            ->first();

        if (! $settlement) {
            Log::warning('[FourElement] Settlement not found for verification', [
                'settlement_number' => $settlementNumber,
            ]);
            $this->error(sprintf('未找到结算单：%s', $settlementNumber));
            return Command::FAILURE;
        }

        Log::info('[FourElement] Start batch four-element verification', [
            'settlement_number' => $settlementNumber,
            'sub_settlement_total' => $settlement->subSettlements->count(),
        ]);

        $this->info(sprintf('开始处理结算单 %s，共 %d 条子结算记录。', $settlementNumber, $settlement->subSettlements->count()));

        $success = 0;
        $failed = 0;

        foreach ($settlement->subSettlements as $subSettlement) {
            if (! in_array($subSettlement->status, [
                SubSettlement::STATUS_PENDING_VERIFY,
                SubSettlement::STATUS_VERIFY_FAILED,
            ], true)) {
                Log::info('[FourElement] Skip sub-settlement verification due to status', [
                    'settlement_number' => $settlementNumber,
                    'sub_settlement_id' => $subSettlement->id,
                    'status' => $subSettlement->status,
                ]);
                $this->line(sprintf('跳过 [%s] %s 当前状态为 %s', $subSettlement->id, $subSettlement->freelancer_name, $subSettlement->status));
                continue;
            }

            try {
                $result = $this->verifySubSettlement($subSettlement);

                if ($result->passed) {
                    $success++;
                    $this->line(sprintf('<info>✓</info> [%s] %s 验证通过', $subSettlement->id, $subSettlement->freelancer_name));
                    $subSettlement->status = SubSettlement::STATUS_PENDING_TAX;
                    $subSettlement->save();

                    Log::info('[FourElement] Sub-settlement verification passed', [
                        'settlement_number' => $settlementNumber,
                        'sub_settlement_id' => $subSettlement->id,
                        'freelancer_id' => $subSettlement->freelancer_id,
                        'message' => $result->message,
                    ]);
                } else {
                    $failed++;
                    $this->line(sprintf('<fg=yellow>✗</> [%s] %s 验证失败：%s', $subSettlement->id, $subSettlement->freelancer_name, $result->message));
                    $subSettlement->status = SubSettlement::STATUS_VERIFY_FAILED;
                    $subSettlement->save();

                    Log::warning('[FourElement] Sub-settlement verification failed', [
                        'settlement_number' => $settlementNumber,
                        'sub_settlement_id' => $subSettlement->id,
                        'freelancer_id' => $subSettlement->freelancer_id,
                        'message' => $result->message,
                    ]);
                }
            } catch (\Throwable $e) {
                $failed++;
                $message = sprintf('四要素验证异常：%s', $e->getMessage());
                $this->line(sprintf('<error>✗</error> [%s] %s %s', $subSettlement->id, $subSettlement->freelancer_name, $message));

                $subSettlement->status = SubSettlement::STATUS_VERIFY_FAILED;
                $subSettlement->status_description = $message;
                $subSettlement->verified_at = now();
                $subSettlement->save();

                Log::error('[FourElement] 验证异常', [
                    'settlement_number' => $settlementNumber,
                    'sub_settlement_id' => $subSettlement->id,
                    'file' => $e->getFile(),
                    'line' => $e->getLine(),
                    'error' => $e->getMessage(),
                ]);
            }
        }

        $hasPending = $settlement->subSettlements()
            ->where('status', '!=', SubSettlement::STATUS_PENDING_TAX)
            ->exists();

        if (! $hasPending && $settlement->subSettlements->isNotEmpty()) {
            $settlement->status = Settlement::STATUS_PENDING_TAX;
            $settlement->save();

            Log::info('[FourElement] Settlement verification complete, status moved to pending tax', [
                'settlement_number' => $settlementNumber,
                'settlement_id' => $settlement->id,
            ]);
        }

        Log::info('[FourElement] Batch four-element verification finished', [
            'settlement_number' => $settlementNumber,
            'success' => $success,
            'failed' => $failed,
        ]);

        $this->info(sprintf('处理完成：成功 %d 条，失败 %d 条。', $success, $failed));

        return Command::SUCCESS;
    }

    protected function verifySubSettlement(SubSettlement $subSettlement): FourElementVerificationResult
    {
        Log::info('[FourElement] Start sub-settlement verification', [
            'sub_settlement_id' => $subSettlement->id,
            'freelancer_id' => $subSettlement->freelancer_id,
        ]);

        $subSettlement->status = SubSettlement::STATUS_VERIFYING;
        $subSettlement->status_description = '正在执行四要素验证';
        $subSettlement->save();

        $result = $this->verifier->verify(
            $subSettlement->freelancer_name,
            (string) $subSettlement->freelancer_phone,
            (string) $subSettlement->freelancer_id_card,
            (string) $subSettlement->freelancer_bank_account
        );

        if ($result->passed) {
            $subSettlement->status = SubSettlement::STATUS_PENDING_SUBMIT;
            $subSettlement->status_description = $result->message;
        } else {
            $subSettlement->status = SubSettlement::STATUS_VERIFY_FAILED;
            $subSettlement->status_description = $result->message;
        }

        $subSettlement->verified_at = now();
        $subSettlement->save();

        Log::info('[FourElement] Sub-settlement verification result persisted', [
            'sub_settlement_id' => $subSettlement->id,
            'status' => $subSettlement->status,
            'message' => $result->message,
        ]);

        return $result;
    }
}
